home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992…ugust: Hack to the Future / ADC Developer CD (1992-08) (''Hack To The Future'')_iso / Dev.CD 199208.iso / Periodicals / develop / develop 7 code / QuickTime / SimpleInMovies / SimpleInWindows.c < prev   
Encoding:
C/C++ Source or Header  |  1992-01-13  |  11.6 KB  |  374 lines  |  [TEXT/MPS ]

  1. /*     
  2. SimpleInMovies
  3.  
  4. Sample programs demonstrating how to open and display
  5. QuickTime™ Movies.
  6.  
  7. SimpleInWindows.c file contains the code for the routines 
  8. having to do with creating closing a maintaining movie windows.
  9.  
  10. Guillermo A. Ortiz
  11. Macintosh Developer Technical Support
  12.  
  13. 08/07/91 Created the file to move in the window calls. Also added code to save
  14. the movie on closing if changes have been made.
  15.  
  16. 08/22/91 -- Added the code to accomodate the fact that the bounds for the controller now enclose the whole movie.
  17. 11/19/91 -- Fixed movie saving code to save correctly after saving as...
  18. 11/21/91 -- Finished the flattening code including the progress stuff.
  19. */
  20.  
  21. #include <SimpleInMovie.h>
  22.  
  23. extern Component movieControllerComponent;
  24. extern long gFlattenMovies;
  25.  
  26. /* ************************************************************************* */
  27. /* Procedures that handle window stuff */
  28.  
  29. Boolean CreateOneWindow(Movie, StandardFileReply, short, short);
  30. Boolean IsAppWindow(WindowPtr);
  31. Boolean    DisposeAllWindows(void);
  32. Boolean    DisposeOneWindow(WindowPtr, short);
  33. Boolean SaveMovie( DocRecHandle, short);
  34. Boolean DoSave(short);
  35. OSErr PutMovieToFile(DocRecHandle, Boolean);
  36.  
  37. extern DialogPtr GetCenteredDialog(short, WindowPtr, WindowPtr);
  38. extern void OutlineDialogItem(DialogPtr, short);
  39. extern pascal Boolean    keyEquivFilter(DialogPtr, EventRecord *, short *);
  40. extern Boolean DisplayPutFile(StandardFileReply *);
  41. extern Rect    CenterWindow(WindowPtr, WindowPtr);
  42. extern OSErr FixMovieWindow(WindowPtr window);
  43.  
  44. extern short gUntitledCount;
  45.  
  46. /* opens a window for the movie and the record that keeps the movie playing
  47.    in the window as well as the instance for the player */
  48. Boolean CreateOneWindow(moov, fileInfo, fileResNum, moovResID)
  49. Movie moov;
  50. StandardFileReply fileInfo;
  51. short fileResNum;
  52. {
  53. WindowPtr        myWindow;
  54. Rect            moovBox;
  55. DocRecHandle    DocHandle;
  56. MovieController localController;
  57. Point where;
  58. OSErr err;
  59. Boolean emptyBox = false;
  60.  
  61. /*     Get our display window.
  62. */
  63.     myWindow = GetNewCWindow(windowID, nil, (WindowPtr) -1); 
  64.     
  65.     if ( myWindow && (DocHandle = (DocRecHandle)NewHandle(sizeof(DocRec))) ) {     /* get storage for            */
  66.       (*DocHandle)->wMovie = moov;                    /* movie                    */
  67.       (*DocHandle)->wFileInfo.sfr = fileInfo;            /* file                        */
  68.       (*DocHandle)->wFileInfo.resFile = fileResNum;
  69.       (*DocHandle)->wFileInfo.moovID = moovResID;
  70.       if ( localController = OpenComponent((Component)movieControllerComponent) ) { /* and component    */
  71.         (*DocHandle)->wPlayer = localController;    /* OpenComponent can move memory so it may not a good idea to dereference the handle in the same line */
  72.         SetWRefCon(myWindow, (long)DocHandle);
  73.         
  74.         /* now size window adding some space at the bottom for controller */
  75.         GetMovieBox(moov,&moovBox); /* Use the movie box to resize window */
  76.         
  77.         where.h = moovBox.left;
  78.         where.v = moovBox.top;
  79.  
  80.         if (err = MCNewAttachedController((*DocHandle)->wPlayer, moov, myWindow, where) )
  81.           DebugStr("\pError at PTNewAttachedController");
  82.                   
  83.         /* now we resize the window according to the controller settings and the
  84.            dimensions of the movie.
  85.         */
  86.         FixMovieWindow(myWindow);
  87.         
  88.         SetWTitle(myWindow,fileInfo.sfFile.name);
  89.             
  90.         SetPort(myWindow);
  91.         
  92.         ShowWindow(myWindow);
  93.         SelectWindow(myWindow);
  94.         
  95.         if (err = MCDoAction((*DocHandle)->wPlayer, mcActionPlay, (Ptr)0x00010000) )
  96.           DebugStr("\pError at MCGetControllerBoundsRect");
  97.  
  98.         return true;
  99.       }
  100.     }
  101.     /* something failed so we have to get rid of the window */
  102.     DisposeWindow(myWindow);
  103.     return(false);
  104. }
  105.  
  106. /* returns true if all windows have been closed */
  107. Boolean    DisposeAllWindows(void)
  108. {
  109.     WindowPtr    window;
  110.     
  111.     while (window = *(WindowPtr *)WindowList) {
  112.  
  113.         /* While we have a front window, try closing it. */
  114.  
  115.         if (!DisposeOneWindow(window, quitCommand)) return(false);
  116.     }
  117.  
  118.     return(true);
  119. }
  120.  
  121.  
  122. /* Closes one window */
  123.  
  124. Boolean    DisposeOneWindow(window, command)
  125. WindowPtr window;
  126. short command;
  127. {
  128.     DocRecHandle    wHndl;
  129.  
  130.     if (IsAppWindow(window)) {
  131.         if (wHndl = (DocRecHandle)GetWRefCon(window)) {     /* Get the storage handle */
  132.           if (SaveMovie(wHndl, command)   )
  133.             return (false);     /* who knows the user hit cancel maybe */
  134.  
  135. /*****     MCRemoveMovie goes away.
  136.           MCRemoveMovie((*wHndl)->wPlayer);
  137. */
  138.           CloseComponent((*wHndl)->wPlayer);            /* and player instance        */
  139.           DisposeMovie((*wHndl)->wMovie);                /* and get rid of movie        */
  140.           if ((*wHndl)->wFileInfo.sfr.sfFile.vRefNum != kInvalVRefNum) {
  141.             if (CloseMovieFile((*wHndl)->wFileInfo.resFile) )/* file open, close it        */
  142.               DebugStr("\pCloseMovieFile failed in DisposeOneWindow"); 
  143.           }
  144.           DisposHandle((Handle)wHndl);                    /* and finally the handle    */
  145.         }
  146.     }
  147.     DisposeWindow(window);
  148.     return(true);
  149. }
  150.  
  151. Boolean IsAppWindow(window)
  152. WindowPtr window;
  153.     if (window)
  154.        return (((WindowPeek)window)->windowKind >= userKind);
  155.     else
  156.       return false;
  157. }
  158. /* *************************************************************** */
  159.  
  160. /* checks that there is a movie associated with the front most window
  161.    and tries to save it; this is used when the save or save as commands
  162.    are executed.
  163.    
  164. */
  165. Boolean DoSave(command)
  166. short command;
  167. {
  168. WindowPtr window;
  169. DocRecHandle wHndl;
  170.  
  171.     if (window = FrontWindow()) { /* don't bother if no movies to play */
  172.       if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) {
  173.         return SaveMovie(wHndl, command);
  174.       }
  175.     }
  176. }
  177.  
  178. /* checks is the movie has to be saved and depending on the command that
  179.    originated the requests saves the movie.
  180.    The next procedures come from the DTS sample MacShell, check it out for more details or
  181.    better comments.    Note though that I have modified the code to accomodate the immediate
  182.    needs, don't blame MacShell.                                    */
  183.    
  184. Boolean SaveMovie( wHndl, command)
  185. DocRecHandle wHndl;
  186. short command;
  187. {
  188.     Str255                closeOrQuit;
  189.     short                item;
  190.     StandardFileReply    reply;
  191.     OSErr                err;
  192.     DialogPtr            saveDialog;
  193.  
  194.     if (command != saveMovieAs) {                        /* If regular save... */
  195.         if (!HasMovieChanged((*wHndl)->wMovie))                /* If movie clean...   */
  196.             return(noErr);                                /* Consider it saved. */
  197.     }
  198.  
  199.     if ((command == closeMovie) || (command == quitCommand)) {
  200.         /* If implicit save... */
  201.  
  202.         GetIndString(closeOrQuit, rMiscStrings,
  203.                      (command == closeMovie) ? sClosing : sQuitting);
  204.         ParamText((*wHndl)->wFileInfo.sfr.sfFile.name, closeOrQuit, nil, nil);
  205.  
  206.         saveDialog = GetCenteredDialog(rYesNoCancel, nil, (WindowPtr)-1L);
  207.  
  208.         if (saveDialog) {
  209.             OutlineDialogItem(saveDialog, kSaveYes);
  210.             ModalDialog((ModalFilterProcPtr)keyEquivFilter, &item);
  211.             DisposDialog(saveDialog);
  212.         }
  213.         else
  214.             item = kSaveYes;
  215.  
  216.         if (item != kSaveYes) {
  217.             err = noErr;
  218.             if (item == kSaveCanceled) err = userCanceledErr;
  219.             return(err);
  220.         }
  221.     }
  222.  
  223.     if (((command == saveMovieAs) ||
  224.         ((*wHndl)->wFileInfo.sfr.sfFile.vRefNum == kInvalVRefNum) )) {
  225.         /* Prompt with SFGetFile if doing a Save As or have never saved before. */
  226.  
  227.         reply = (*wHndl)->wFileInfo.sfr;
  228.         
  229.         if (!DisplayPutFile(&(reply)))
  230.             return(userCanceledErr);
  231.                 /* User canceled the save. */
  232.  
  233.         if ((*wHndl)->wFileInfo.sfr.sfFile.vRefNum != kInvalVRefNum) {
  234.             if (err = CloseMovieFile((*wHndl)->wFileInfo.resFile) )
  235.               DebugStr("\pCloseMovieFile failed in SaveMovie"); 
  236.                 /* Close the old file.  Don't respond to any error here because
  237.                 ** the user may be trying to do a save-as because their old file
  238.                 ** is bad.  If we fail to close the old file, and then respond
  239.                 ** to the error, the user won't get the opportunity to save
  240.                 ** their document to a new file.
  241.                 */
  242.         }
  243.         SetWTitle(FrontWindow(),reply.sfFile.name);
  244.         (*wHndl)->wFileInfo.sfr = reply;
  245.         if ( err = PutMovieToFile(wHndl, true) ) {
  246.           reply.sfFile.vRefNum = kInvalVRefNum;
  247.           DebugStr("\pCouldn't create the new file for save as");
  248.         }
  249.     }
  250.     else /* saving into an existing file */
  251.       if (err = PutMovieToFile(wHndl, false) ) {
  252.         (*wHndl)->wFileInfo.sfr.sfFile.vRefNum = kInvalVRefNum;
  253.         return(err);
  254.       }
  255.     
  256.     ClearMovieChanged((*wHndl)->wMovie);
  257.     return(noErr);
  258. }
  259.  
  260. /* The progress proc lets the user know what is going on while a FlattenMovie call
  261.    is being done.
  262. */
  263. pascal OSErr flattenProgressProc(Movie m, short message, short operation, Fixed percent, long refCon)
  264. {
  265. #pragma unused (m)
  266.  
  267. WindowPtr    pDialog;
  268. Fixed        percentFix = 0x00640000;  /* hundred in fixed */
  269. short        percentShort;
  270. Rect        windRect,
  271.             progressRect= {100,20,120,200};
  272. GrafPtr        oldPort;
  273.  
  274.     if (operation != progressOpFlatten)    /* This should only be called for flatten */
  275.       return featureUnsupported;            
  276.     else                                            /* OK this I know about                            */
  277.       switch (message) {
  278.         case movieProgressOpen:
  279.           SetRect(&windRect,20,20,240,200);
  280.           pDialog = NewCWindow(nil,&windRect,"",false, dBoxProc, (WindowPtr)-1L,true,0);
  281.           CenterWindow(pDialog, nil);
  282.           if (pDialog) {
  283.               GetPort(&oldPort);
  284.               ShowWindow(pDialog);
  285.             SetPort(pDialog);
  286.             MoveTo(30,50);
  287.             DrawString("\pFlattening in progress …");
  288.             FrameRect(&progressRect);
  289.               *(WindowPtr *)refCon = pDialog; 
  290.             SetPort(oldPort);
  291.               return noErr;
  292.           }
  293.         break;
  294.         case movieProgressUpdatePercent:
  295.           GetPort(&oldPort);
  296.           SetPort(*(WindowPtr *)refCon);
  297.           percentFix = FixMul(percent, percentFix);
  298.             percentShort = FixRound(percentFix);
  299.           FrameRect(&progressRect);
  300.           InsetRect(&progressRect,2,2);
  301.           progressRect.right = progressRect.left+((progressRect.right - progressRect.left) * percentShort/100);
  302.           PaintRect(&progressRect);
  303.           SetPort(oldPort);                         
  304.           return noErr;
  305.         break;
  306.         case movieProgressClose:
  307.           DisposeWindow(*(WindowPtr *)refCon);
  308.           return noErr;
  309.         break;
  310.       }
  311. }
  312.  
  313.  
  314. OSErr PutMovieToFile(wHndl, newFile)
  315. DocRecHandle    wHndl;
  316. Boolean            newFile;
  317. {
  318. OSErr theErr;
  319. short    resFile, 
  320.         resID = 0; /* resource id = 0 tells the MovieToolbox to come up with a number */
  321. DialogPtr flattenDialog;     /* the progress proc stores here its dialog pointer */
  322.  
  323.     resFile = CurResFile();
  324.     if (newFile) {
  325.       if ( gFlattenMovies) {
  326.       
  327.           /* Brackett Flatten movie with SetMovieProgress proc calls so that the user
  328.            gets to know what is going on if the flattening takes too long.
  329.            It is also important to lock the handle containing the movie reference,
  330.            FlattenMovie moves data around and since we are dereferencing the handle
  331.            the pointer we pass could end up pointing to garbage.
  332.         */
  333.         HLock((Handle)wHndl);
  334.         SetMovieProgressProc((*wHndl)->wMovie, flattenProgressProc, (long) &flattenDialog);
  335.  
  336.         FlattenMovie((*wHndl)->wMovie, 0 /* flags */, 
  337.                      &((*wHndl)->wFileInfo.sfr.sfFile), 'TVOD',0,
  338.                      createMovieFileDeleteCurFile /* createMovieFileFlags*/,
  339.                       &resID, nil /* resName */);
  340.  
  341.         HUnlock((Handle)wHndl);
  342.         if (theErr = GetMoviesError())
  343.           DebugStr("\pFlattenMovie failed");
  344.         else
  345.           (*wHndl)->wFileInfo.moovID = resID;        /* remember the moov resource id */
  346.  
  347.         SetMovieProgressProc((*wHndl)->wMovie, nil, 0); /* flattening is done remove proc */
  348.  
  349.         if (theErr = OpenMovieFile( &((*wHndl)->wFileInfo.sfr.sfFile),
  350.                                     &((*wHndl)->wFileInfo.resFile),fsRdWrPerm))
  351.           DebugStr("\pOpenMovieFile failed");
  352.       }
  353.       else /* do not flatten */
  354.         {
  355.           if ( !(theErr = CreateMovieFile(  &((*wHndl)->wFileInfo.sfr.sfFile), 'TVOD',0,createMovieFileDeleteCurFile, 
  356.                                      &((*wHndl)->wFileInfo.resFile), nil) )) {
  357.             if (theErr = AddMovieResource((*wHndl)->wMovie, (*wHndl)->wFileInfo.resFile, 
  358.                                         &resID, nil /* resName */) )
  359.               DebugStr("\pAddMovieResource failed in PutMovieToFile");
  360.             else
  361.              (*wHndl)->wFileInfo.moovID = resID;        /* remember the moov resource id */
  362.           }
  363.           else DebugStr("\pCreateMovieFile Failed in PutMovieToFile");
  364.         }
  365.     }
  366.     else 
  367.       if (theErr = UpdateMovieResource( (*wHndl)->wMovie, (*wHndl)->wFileInfo.resFile, 
  368.                                     (*wHndl)->wFileInfo.moovID, nil))
  369.         DebugStr("\pPutMovieToFile: UpdateMovieResource failed");
  370.  
  371.     UseResFile(resFile);
  372.     return (theErr);
  373. }